home *** CD-ROM | disk | FTP | other *** search
/ Aminet 37 / Aminet 37 (2000)(Schatztruhe)[!][Jun 2000].iso / Aminet / dev / lang / sofa.lha / sofa / smalleiffel / lib_number / large_positive_integer.e < prev    next >
Text File  |  2000-03-25  |  11KB  |  420 lines

  1. -- This file is  free  software, which  comes  along  with  SmallEiffel. This
  2. -- software  is  distributed  in the hope that it will be useful, but WITHOUT 
  3. -- ANY  WARRANTY;  without  even  the  implied warranty of MERCHANTABILITY or
  4. -- FITNESS  FOR A PARTICULAR PURPOSE. You can modify it as you want, provided
  5. -- this header is kept unaltered, and a notification of the changes is added.
  6. -- You  are  allowed  to  redistribute  it and sell it, alone or as a part of 
  7. -- another product.
  8. --          Copyright (C) 1994-98 LORIA - UHP - CRIN - INRIA - FRANCE
  9. --            Dominique COLNET and Suzanne COLLIN - colnet@loria.fr 
  10. --                       http://SmallEiffel.loria.fr
  11. --
  12. class LARGE_POSITIVE_INTEGER
  13. --
  14. -- To implement NUMBER (do not use this class, see NUMBER).
  15. --
  16.     
  17. inherit LARGE_INTEGER;
  18.    
  19. creation make_from_fixed_array, make_smaller, make_from_product, make_big
  20.    
  21. feature
  22.  
  23.    is_positive: BOOLEAN is true;
  24.    
  25.    is_negative: BOOLEAN is false;
  26.    
  27.    to_integer: INTEGER is
  28.       do
  29.      check false end;
  30.       end;
  31.    
  32.    to_double: DOUBLE is
  33.       do
  34.      Result := fixed_array_to_double(value);
  35.       end;
  36.    
  37.    prefix "-" : NUMBER is
  38.       do
  39.      if (value.item(1) = 1) and (value.item(0) = 0) then
  40.         !SMALL_INTEGER!Result.make(-Base);
  41.      else
  42.         !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(value);
  43.      end;
  44.       end;
  45.    
  46.    
  47.    infix "+" (other: NUMBER): NUMBER is
  48.       do
  49.      Result := other.add_with_large_positive_integer(Current);
  50.       end;
  51.  
  52. feature {NUMBER}
  53.    
  54.    add_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): NUMBER is
  55.       do
  56.      add_fixed_arrays(value, other.value);
  57.      !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  58.       end;
  59.    
  60.    add_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): NUMBER is
  61.       do
  62.      if fixed_array_greater_than(value, other.value) then
  63.         difference_between_fixed_arrays(value, other.value);
  64.         Result := create_positive(temp);
  65.      else
  66.         difference_between_fixed_arrays(other.value, value);
  67.         Result := create_negative(temp);
  68.      end;
  69.       end;
  70.    
  71.    add_with_small_fraction (other: SMALL_FRACTION ): NUMBER is
  72.       do
  73.      Result := other.add_with_large_positive_integer( Current );
  74.       end;
  75.       
  76.    add_with_large_fraction (other: LARGE_FRACTION): NUMBER is
  77.       do
  78.      Result := other.add_with_large_positive_integer( Current );
  79.       end;
  80.  
  81.    infix "@+" (other: INTEGER): NUMBER is
  82.       do     
  83.      if (other >= 0) then
  84.         temp_1_digint.put(other, 0);
  85.         add_fixed_arrays(value, temp_1_digint);
  86.         !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  87.      else
  88.         if (other /= Minimum_integer) then
  89.            temp_1_digint.put(other.abs, 0);
  90.            difference_between_fixed_arrays(value, temp_1_digint);
  91.         else
  92.            temp_2_digints.put(0,0);
  93.            temp_2_digints.put(1,1);
  94.            difference_between_fixed_arrays(value, temp_2_digints);
  95.         end;
  96.         Result := create_positive(temp);
  97.      end;
  98.       end; 
  99.       
  100. feature {NUMBER} -- Multiplication
  101.    
  102.    infix "*" (other: NUMBER): NUMBER is
  103.       do
  104.      Result := other.multiply_with_large_positive_integer(Current);
  105.       end;
  106.    
  107.    multiply_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): NUMBER is
  108.       do
  109.      mult_2_fixed(value, other.value);
  110.      !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp_from_mult));
  111.       end;
  112.    
  113.    multiply_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): NUMBER is
  114.       do 
  115.      mult_2_fixed(value, other.value);
  116.      !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(clone(temp_from_mult));
  117.       end;
  118.    
  119.    multiply_with_small_fraction (other: SMALL_FRACTION ): NUMBER is
  120.       do
  121.      Result := other.multiply_with_large_positive_integer(Current);
  122.       end;
  123.    
  124.    multiply_with_large_fraction (other: LARGE_FRACTION ): NUMBER is
  125.       do
  126.      Result := other.multiply_with_large_positive_integer(Current);
  127.       end; 
  128.    
  129.    infix "@*"(other : INTEGER): NUMBER is
  130.       do
  131.      if (other = 0) then
  132.         Result := zero;
  133.      elseif (other > 0) then 
  134.         mult_fixed_with_integer(value, other);
  135.         !LARGE_POSITIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  136.      else
  137.         if (other = Minimum_integer) then
  138.            mult_2_fixed(value, smaller_correct_fixed);
  139.            !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(clone(temp_from_mult));
  140.         else
  141.            mult_fixed_with_integer(value, other.abs);
  142.            !LARGE_NEGATIVE_INTEGER!Result.make_from_fixed_array(clone(temp));
  143.         end;
  144.      end;
  145.       end;
  146.    
  147.    
  148. feature {NUMBER} -- division
  149.    
  150.    infix "@/"(other : INTEGER): NUMBER is
  151.       local
  152.      den: ABSTRACT_INTEGER;
  153.       do
  154.      if (other = 1) then
  155.         Result := Current;
  156.      else
  157.         if (other = Minimum_integer) then
  158.            divise_fixed_array(value, smaller_correct_fixed);
  159.         else
  160.            temp_1_digint.put(other.abs,0);
  161.            divise_fixed_array(value, temp_1_digint);
  162.         end;
  163.         if (temp_remainder.upper < 0) then
  164.            if (other < 0) then 
  165.           Result := create_negative(temp_quotient);
  166.            else
  167.           Result := create_positive(temp_quotient);
  168.            end;
  169.         else
  170.            if (other = Minimum_integer) then
  171.           den := greater_large_negative_integer;
  172.           !LARGE_FRACTION!Result.make_simply(Current, den, true);
  173.            else
  174.           !SMALL_INTEGER!den.make(other);
  175.           !LARGE_FRACTION!Result.make_simply(Current, den, (other < 0));
  176.            end;
  177.         end;
  178.      end;
  179.       end;
  180.  
  181.    -- Integer division
  182.    
  183.    infix "//" (other: NUMBER): NUMBER is
  184.       local
  185.      oth: ABSTRACT_INTEGER;
  186.       do
  187.      oth ?= other;
  188.      Result := oth.integer_divide_large_positive_integer(Current);
  189.       end;
  190.    
  191.    integer_divide_small_integer(other: SMALL_INTEGER): ABSTRACT_INTEGER is
  192.       do
  193.      if (other @= Minimum_integer) then
  194.         divise_fixed_array(smaller_correct_fixed, value);
  195.         Result := create_negative(temp_quotient);
  196.      else    
  197.         temp_1_digint.put(other.to_integer.abs,0); 
  198.         divise_fixed_array(temp_1_digint, value);
  199.         if (other @< 0) then
  200.            Result := create_negative(temp_quotient);
  201.         else
  202.            Result := create_positive(temp_quotient);
  203.         end;
  204.      end;
  205.       end; 
  206.       
  207.    integer_divide_large_positive_integer(other: LARGE_POSITIVE_INTEGER): ABSTRACT_INTEGER is
  208.       do
  209.      divise_fixed_array(other.value, value);
  210.      Result := create_positive(temp_quotient);
  211.       end;
  212.    
  213.    integer_divide_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): ABSTRACT_INTEGER is
  214.       do      
  215.      divise_fixed_array(other.value, value);
  216.      Result := create_negative(temp_quotient);
  217.       end;
  218.    
  219.    infix "@//"(other : INTEGER): NUMBER is
  220.       do
  221.      if (other = Minimum_integer) then
  222.         divise_fixed_array(value, smaller_correct_fixed);
  223.         Result := create_negative(temp_quotient);
  224.      else    
  225.         temp_1_digint.put(other.abs,0);
  226.         divise_fixed_array(value, temp_1_digint);
  227.         if (other < 0) then
  228.            Result := create_negative(temp_quotient);
  229.         else
  230.            Result := create_positive(temp_quotient);
  231.         end;
  232.      end;
  233.       end;
  234.  
  235.    -- Remainder of an integer division
  236.    
  237.    infix "\\" (other: NUMBER): NUMBER is
  238.       local
  239.      oth: ABSTRACT_INTEGER;
  240.       do
  241.      oth ?= other;
  242.      Result := oth.remainder_of_divide_large_positive_integer(Current);
  243.       end;
  244.    
  245.    remainder_of_divide_small_integer(other: SMALL_INTEGER): ABSTRACT_INTEGER is
  246.       do
  247.      if (other @= Minimum_integer) then
  248.         divise_fixed_array(smaller_correct_fixed, value);
  249.         Result := create_negative(temp_remainder);
  250.      else    
  251.         temp_1_digint.put(other.to_integer.abs,0);
  252.         divise_fixed_array(temp_1_digint, value);
  253.         if (other @< 0) then
  254.            Result := create_negative(temp_remainder);
  255.         else
  256.            Result := create_positive(temp_remainder);
  257.         end;
  258.      end;
  259.       end; 
  260.       
  261.    remainder_of_divide_large_positive_integer(other: LARGE_POSITIVE_INTEGER): ABSTRACT_INTEGER is
  262.       do
  263.      divise_fixed_array(other.value, value);
  264.      Result := create_positive(temp_remainder);
  265.       end;
  266.    
  267.    remainder_of_divide_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): ABSTRACT_INTEGER is
  268.       do
  269.      divise_fixed_array(other.value, value);
  270.      Result := create_negative(temp_remainder);
  271.       end;
  272.  
  273.    infix "@\\" (other: INTEGER): NUMBER is
  274.       do
  275.      if (other = Minimum_integer) then
  276.         divise_fixed_array(value, smaller_correct_fixed);
  277.         Result := create_negative(temp_remainder);
  278.      else    
  279.         temp_1_digint.put(other.abs,0);
  280.         divise_fixed_array(value, temp_1_digint);
  281.         if (other < 0) then
  282.            Result := create_negative(temp_remainder);
  283.         else
  284.            Result := create_positive(temp_remainder);
  285.         end;
  286.      end;        
  287.       end;
  288.    
  289.    
  290. feature {NUMBER} -- inverse   
  291.    
  292.    inverse: NUMBER is
  293.       local
  294.      num: ABSTRACT_INTEGER;
  295.       do
  296.      num ?= one;
  297.      !LARGE_FRACTION!Result.make_simply(num, Current, false);
  298.       end;
  299.       
  300.    
  301. feature -- comparisons with INTEGER
  302.    
  303.    infix "@=" (other: INTEGER): BOOLEAN is
  304.       do
  305.       end;
  306.    
  307.    infix "@<" (other: INTEGER): BOOLEAN is
  308.       do
  309.       end;
  310.    
  311.    infix "@>" (other: INTEGER): BOOLEAN is 
  312.       do
  313.      Result := true;
  314.       end;
  315.    
  316.    infix "@>=" (other: INTEGER): BOOLEAN is 
  317.       do
  318.      Result := true;
  319.       end;
  320.    
  321.    infix "@<=" (other: INTEGER): BOOLEAN is 
  322.       do
  323.       end;
  324.    
  325. feature -- comparisons with NUMBER
  326.    
  327.    infix "<" (other: NUMBER): BOOLEAN is
  328.       do
  329.      Result := other.greater_with_large_positive_integer(Current);
  330.       end;
  331.    
  332. feature -- comparisons with DOUBLE 
  333.    
  334.    infix "#=" (other: DOUBLE): BOOLEAN is
  335.       do
  336.      if other <= Maximum_integer then
  337.      else
  338.         Result := to_double = other;
  339.      end;
  340.       end;
  341.    
  342.    infix "#<" (other: DOUBLE): BOOLEAN is
  343.       do
  344.      if other <= Maximum_integer then
  345.      else
  346.         Result := to_double < other;
  347.      end;
  348.       end;
  349.    
  350.    infix "#<=" (other: DOUBLE): BOOLEAN is
  351.       do
  352.      if other <= Maximum_integer then
  353.      else
  354.         Result := to_double <= other;
  355.      end;
  356.       end;
  357.    
  358.    infix "#>" (other: DOUBLE): BOOLEAN is
  359.       do
  360.      if other <= Maximum_integer then
  361.         Result := true 
  362.      else
  363.         Result := to_double > other;
  364.      end;
  365.       end;
  366.    
  367.    infix "#>=" (other: DOUBLE): BOOLEAN is
  368.       do
  369.      if other <= Maximum_integer then
  370.         Result := true
  371.      else
  372.         Result := to_double >= other;
  373.      end;
  374.       end;
  375.    
  376. feature {NUMBER}
  377.    
  378.    greater_with_large_positive_integer(other: LARGE_POSITIVE_INTEGER): BOOLEAN is 
  379.       local
  380.      i: INTEGER;
  381.       do      
  382.      if (value.upper = other.value.upper) then
  383.         from
  384.            i := value.upper;
  385.         variant
  386.            i
  387.         until
  388.            (i < value.lower) or else (value.item(i) /= other.value.item(i))
  389.         loop
  390.            i := i - 1;
  391.         end;        
  392.         Result := (i /= value.lower - 1) 
  393.            and then (value.item(i) > other.value.item(i));
  394.      else        
  395.         Result := (value.upper > other.value.upper);  
  396.      end;
  397.       end;   
  398.    
  399.    greater_with_large_negative_integer(other: LARGE_NEGATIVE_INTEGER): BOOLEAN is 
  400.       once
  401.      Result := true;
  402.       end;
  403.    
  404.    greater_with_small_fraction (other: SMALL_FRACTION): BOOLEAN is
  405.       once
  406.      Result := true;
  407.       end;   
  408.    
  409.    greater_with_large_fraction (other: LARGE_FRACTION): BOOLEAN is
  410.       do
  411.      Result := not other.greater_with_large_positive_integer(Current);
  412.       end;   
  413.    
  414.    
  415. end -- LARGE_POSITIVE_INTEGER
  416.  
  417.  
  418.  
  419.  
  420.